package com.sale.salesystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sale.salesystem.entity.DashboardInfo;
import com.sale.salesystem.entity.DashboardPermission;
import com.sale.salesystem.entity.SysUser;
import com.sale.salesystem.exception.BusinessException;
import com.sale.salesystem.mapper.DashboardInfoMapper;
import com.sale.salesystem.mapper.DashboardPermissionMapper;
import com.sale.salesystem.mapper.UserMapper;
import com.sale.salesystem.service.DashboardPermissionService;
import com.sale.salesystem.vo.DashboardPermissionVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class DashboardPermissionServiceImpl implements DashboardPermissionService {

    private final DashboardInfoMapper dashboardInfoMapper;
    private final DashboardPermissionMapper permissionMapper;
    private final UserMapper userMapper;

    @Override
    public DashboardPermissionVO getDashboardInfo(Long dashboardId) {
        DashboardInfo dashboard = dashboardInfoMapper.selectById(dashboardId);
        if (dashboard == null) {
            throw new BusinessException("仪表板不存在");
        }

        return convertToVO(dashboard);
    }

    @Override
    public DashboardPermissionVO getVisitors(Long dashboardId) {
        DashboardInfo dashboard = dashboardInfoMapper.selectById(dashboardId);
        if (dashboard == null) {
            throw new BusinessException("仪表板不存在");
        }

        return convertToVO(dashboard);
    }

    @Override
    @Transactional
    public void addVisitor(Long dashboardId, String username) {
        // 检查仪表板是否存在
        DashboardInfo dashboard = dashboardInfoMapper.selectById(dashboardId);
        if (dashboard == null) {
            throw new BusinessException("仪表板不存在");
        }

        // 根据用户名查找用户
        SysUser visitor = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, username));
        if (visitor == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查是否已有权限
        if (hasPermission(visitor.getId(), dashboardId)) {
            throw new BusinessException("用户已有权限");
        }

        // 添加权限
        DashboardPermission permission = new DashboardPermission();
        permission.setDashboardId(dashboardId);
        permission.setVisitorId(visitor.getId());
        permissionMapper.insert(permission);
    }

    @Override
    @Transactional
    public void removeVisitor(Long dashboardId, String username) {
        // 根据用户名查找用户
        SysUser visitor = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, username));
        if (visitor == null) {
            throw new BusinessException("用户不存在");
        }

        permissionMapper.delete(new LambdaQueryWrapper<DashboardPermission>()
                .eq(DashboardPermission::getDashboardId, dashboardId)
                .eq(DashboardPermission::getVisitorId, visitor.getId()));
    }

    @Override
    @Transactional
    public void transferOwner(Long dashboardId, String newOwnerUsername) {
        // 检查仪表板是否存在
        DashboardInfo dashboard = dashboardInfoMapper.selectById(dashboardId);
        if (dashboard == null) {
            throw new BusinessException("仪表板不存在");
        }

        // 根据用户名查找新所有者
        SysUser newOwner = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, newOwnerUsername));
        if (newOwner == null) {
            throw new BusinessException("用户不存在");
        }

        // 更新所有者
        dashboard.setOwnerId(newOwner.getId());
        dashboardInfoMapper.updateById(dashboard);
    }

    @Override
    public boolean hasPermission(Long userId, Long dashboardId) {
        // 检查用户是否存在
        SysUser user = userMapper.selectById(userId);
        if (user == null) {
            return false;
        }

        // 如果是管理员，直接返回true
        if ("ADMIN".equals(user.getRole())) {
            return true;
        }

        DashboardInfo dashboard = dashboardInfoMapper.selectById(dashboardId);
        if (dashboard == null) {
            return false;
        }

        // 是否是所有者
        if (dashboard.getOwnerId().equals(userId)) {
            return true;
        }

        // 是否是访问者
        return permissionMapper.existsByDashboardIdAndVisitorId(dashboardId, userId);
    }

    @Override
    public boolean hasPermission(Long userId, String type) {
        // 检查用户是否存在
        SysUser user = userMapper.selectById(userId);
        if (user == null) {
            return false;
        }

        // 如果是管理员，直接返回true
        if ("ADMIN".equals(user.getRole())) {
            return true;
        }

        // 查询用户是否有该类型仪表板的访问权限
        return permissionMapper.existsByVisitorIdAndDashboardType(userId, type);
    }

    @Override
    public List<String> getUserAccessibleDashboardTypes(Long userId) {
        // 检查用户是否存在
        SysUser user = userMapper.selectById(userId);
        if (user == null) {
            return Collections.emptyList();
        }

        // 如果是管理员，返回所有类型
        if ("ADMIN".equals(user.getRole())) {
            return dashboardInfoMapper.selectAllTypes();
        }

        // 返回用户有权限的仪表板类型
        return permissionMapper.selectAccessibleTypesByUserId(userId);
    }

    @Override
    public List<DashboardPermissionVO> getUserDashboards(Long userId) {
        List<DashboardPermissionVO> result = new ArrayList<>();
        
        // 获取用户拥有的仪表板
        List<DashboardInfo> ownedDashboards = dashboardInfoMapper.selectByOwnerId(userId);
        for (DashboardInfo dashboard : ownedDashboards) {
            DashboardPermissionVO vo = convertToVO(dashboard);
            vo.setIsOwner(true);
            vo.setHasPermission(true);
            result.add(vo);
        }
        
        // 获取用户可访问的仪表板
        List<DashboardPermission> permissions = permissionMapper.selectByVisitorId(userId);
        for (DashboardPermission permission : permissions) {
            DashboardInfo dashboard = dashboardInfoMapper.selectById(permission.getDashboardId());
            if (dashboard != null) {
                DashboardPermissionVO vo = convertToVO(dashboard);
                vo.setIsOwner(false);
                vo.setHasPermission(true);
                result.add(vo);
            }
        }
        
        return result;
    }

    private DashboardPermissionVO convertToVO(DashboardInfo dashboard) {
        DashboardPermissionVO vo = new DashboardPermissionVO();
        vo.setDashboardId(dashboard.getId());
        vo.setIcon(dashboard.getIcon());
        vo.setDashboardName(dashboard.getName());
        vo.setDashboardType(dashboard.getType());
        vo.setCreateTime(dashboard.getCreateTime());
        vo.setUpdateTime(dashboard.getUpdateTime());

        // 获取所有者信息
        SysUser owner = userMapper.selectById(dashboard.getOwnerId());
        vo.setOwnerName(owner != null ? owner.getUsername() : null);

        // 获取访问者信息
        List<DashboardPermission> permissions = permissionMapper.selectList(
                new LambdaQueryWrapper<DashboardPermission>()
                        .eq(DashboardPermission::getDashboardId, dashboard.getId()));

        // 优化：一次性查询所有用户
        if (!permissions.isEmpty()) {
            List<Long> visitorIds = permissions.stream()
                    .map(DashboardPermission::getVisitorId)
                    .collect(Collectors.toList());

            List<SysUser> visitors = userMapper.selectBatchIds(visitorIds);
            Map<Long, String> userMap = visitors.stream()
                    .collect(Collectors.toMap(SysUser::getId, SysUser::getUsername));

            List<String> visitorNames = permissions.stream()
                    .map(permission -> userMap.get(permission.getVisitorId()))
                    .collect(Collectors.toList());

            vo.setVisitorNames(visitorNames);
        } else {
            vo.setVisitorNames(Collections.emptyList());
        }

        // 设置默认权限
        vo.setIsOwner(false);
        vo.setHasPermission(false);

        return vo;
    }
}